/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package facade;

import entities.Customer;
import entities.CustomerPK;
import entities.CustomerRequest;
import entities.EmailPyme;
import entities.Product;
import entities.ProductXsales;
import entities.ProductXsalesPK;
import entities.Pyme;
import entities.Sales;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

/**
 *
 * @author Andrés Felipe
 */
public abstract class AbstractFacade<T> {
    private Class<T> entityClass;
    

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);      
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }
    
    public void refresh(T entity) {
       // getEntityManager().flush();
        getEntityManager().refresh(entity);
       
    }
    
    public void flush() {
        getEntityManager().flush();
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {           
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }
    
    public List<List<String>> getProductsInformation(int pymeIdentification, int toSell) {
        EntityManager em = getEntityManager();
        TypedQuery<T> query = em.createNamedQuery("Product.findByToSellToId", entityClass).setParameter("pymeIdentification", pymeIdentification).setParameter("toSell", toSell);
        List<Product> products = (List<Product>) query.getResultList();
        List<List<String>> result = new ArrayList<>();
        for (int i = 0; i < products.size(); i++)
        {
            List<String> row = new ArrayList<>();
            row.add(products.get(i).getIdproduct().toString());
            row.add(products.get(i).getName());
            row.add(String.valueOf(products.get(i).getPrice()));
            if (products.get(i).getDatamaster() == null)
                row.add(" ");
            else
                row.add(products.get(i).getDatamaster());
            result.add(row);
        }
        return result;
    }
    
    
     public T getIdRequest(String customerIdentification , int pymeIdentification, Date date) {
        EntityManager em = getEntityManager();
        TypedQuery<T> query = em.createNamedQuery("CustomerRequest.findIdRequest", entityClass).setParameter("customerIdentification", customerIdentification).setParameter("pymeIdentification", pymeIdentification).setParameter("creationdate", date);
        return query.getSingleResult();
    }
     
     public T getSaleId(String customerIdentification , int pymeIdentification, Date dateCreate , Date dateDelivery) {
        EntityManager em = getEntityManager();
        TypedQuery<T> query = em.createNamedQuery("Sales.findSaleId", entityClass).setParameter("customerIdentification", customerIdentification).setParameter("pymeIdentification", pymeIdentification).setParameter("creationdate", dateCreate).setParameter("deliverydate", dateDelivery);
        return query.getSingleResult();
    }
     
     public List<List<String>> getAllPymes(){
         
         List<List<String>> result = new ArrayList<>();
         List<Pyme> pymes = (List<Pyme>) this.findAll();      
         for(int i = 0; i < pymes.size(); i++) 
         {
            List<String> row = new ArrayList<>();
            row.add(pymes.get(i).getName());
            row.add(pymes.get(i).getIdentification().toString());
            row.add(pymes.get(i).getAddress().toString());
            result.add(row);
         }
         return result;
     }
     
     public List<String> getCustomerInformation(String customerIdentification, long pymeIdentification){
         
         List<String> row = new ArrayList<>();
         CustomerPK key = new CustomerPK();
         key.setIdentification(customerIdentification);
         key.setPymeidentification((int) pymeIdentification);     
         Customer customer = (Customer) this.find(key);
         if (customer == null) {
             return new ArrayList<>();
         }
         row.add(customer.getName());
         row.add(customer.getEmail());
         row.add(customer.getPhone());
         row.add(customer.getAddress());
         
         return row; 
     }
     
     public void newCustomer(String identification, int pymeIndentification, String name, String adress, String email, String phone) {
           
          CustomerPK pk = new CustomerPK(identification, pymeIndentification);
          Customer customer = new Customer(pk, name, adress, email, phone);   
          this.create((T) customer);      
    }
     
    public List<String> getEmailPyme(int pymeIdentification)
    {     
        List<String> datos = new ArrayList<>();
        Pyme pyme = (Pyme) this.find(pymeIdentification);
        List<EmailPyme> emails = pyme.getEmailPymeList();
        EmailPyme em = emails.get(0);
        datos.add(em.getHost());
        datos.add(em.getPort());
        datos.add(em.getUsername());
        datos.add(em.getPassword());
        return datos;
    }
    
    public long getIdRequest(String customerIdentification,int pymeId) {
        
        Date date = new Date();     
        CustomerRequest request = new CustomerRequest();
        request.setCustomeridentification(new Customer(customerIdentification, pymeId));
        request.setCreationdate(date);
        this.create((T) request);
        request = (CustomerRequest) this.getIdRequest(customerIdentification, pymeId, date);
        System.out.println("IDRESQUEST --------- >  " + request.getIdrequest());
        return Long.valueOf(String.valueOf(request.getIdrequest()));
    
    }
    
    public int getSaleId(String customerIdentification,int pymeId,double total,Date date) {
    
        Date newDate = new Date ();
        Sales sales = new Sales();
        Customer customer = new Customer();
        CustomerPK key = new CustomerPK();
        key.setIdentification(customerIdentification);
        key.setPymeidentification(pymeId);
        customer.setCustomerPK(key);
        sales.setCustomeridentification(customer);
        sales.setDeliverydate(date);
        sales.setCreationdate(newDate);
        sales.setTotal(Double.valueOf(String.valueOf(total)).intValue());             
        this.create((T) sales);
        sales = (Sales) this.getSaleId(customerIdentification, pymeId, newDate, date);
        return sales.getSaleid();
                    
    }
    
    public void saveCustomerPurchase(int saleId, int productId , double quantity, ArrayList<ArrayList<Object>> customerRequest) {

        ProductXsalesPK keySales = new ProductXsalesPK(productId, saleId);
        ProductXsales pxs = new ProductXsales();
        pxs.setProductXsalesPK(keySales);
        //System.out.println("paso");
        this.create((T) pxs);
        //System.out.println("paso");
         
    }
}
